#include <iostream>
#include <vector>
#include <string>
#include <functional>
#include <unistd.h>
#include <pthread.h>

using namespace std;

// 定义一个条件变量
pthread_cond_t cond;

// 定义一个互斥锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 当前不用，但是接口需要，所以我们需要留下来

// 函数封装器
vector<function<void()>> funcs;
 
void show()
{
    cout << "hello show" << endl;
}

void print()
{
    cout << "hello print" << endl;
}

// 定义全局退出变量
volatile bool quit = false;

// 三个线程都会调用这个函数
void *waitCommand(void *args)
{
    pthread_detach(pthread_self());
    string name = static_cast<char*>(args);

    // 如果不退出一直去运行
    while (!quit)
    {
        // 执行了下面的代码，证明某一种条件不就绪(现在还没有场景)，要我这个线程等待
        // 三个线程，都会进在条件变量下进行排队**
        pthread_cond_wait(&cond, &mutex); // 让对应的线程进行等待，等待被唤醒

        // for(auto &f : funcs)
        // {
        //     f();
        // }
        cout << "thread id: " << pthread_self() << " end... " << name << endl;
    }

    return nullptr;
}

int main()
{
    funcs.push_back(show);
    funcs.push_back(print);
    funcs.push_back([](){
        cout << "你好世界!" << endl;
    });

    // 初始化一个条件变量
    pthread_cond_init(&cond, nullptr);

    // 创建三个线程
    pthread_t t1, t2, t3;
    pthread_create(&t1, nullptr, waitCommand, (void*)"thread1");
    pthread_create(&t2, nullptr, waitCommand, (void*)"thread2");
    pthread_create(&t3, nullptr, waitCommand, (void*)"thread3");

    // 主线程控制
    while(true)
    {
        // other code, 

        // 主线程将所有线程唤醒并做事情，1秒唤醒一次
        // sleep(1);
        // pthread_cond_broadcast(&cond);

        char n = 'a';

        // cin和cout在交叉使用的时候，缓冲区会做强制刷新
        cout << "请输入你的command(n/q): ";
        cin >> n;

        if(n == 'n') pthread_cond_signal(&cond); // 唤醒在特定条件变量下等的线程
        else break;
        
        usleep(100);
    }
    
    // sleep(1);
    cout << "main thread quit" << endl;

    // 释放条件变量
    pthread_cond_destroy(&cond);

    return 0;
}
